Доброго времени суток ,
Возник такой вопрос. Допусти у меня есть объект класса. Который в свою очередь имеет
просто поля и методы. То есть можно бы было заменить структурой (даже и без методов).
Место для него я выделяю в динамической памяти подобно этому
someObj* objPointer = new someObj();
То есть этот класс выступает в роли просто контейнера данных и работы с ними.
Вопрос в том, как правильно очистить память от этого класса? Допустим если у меня
в есть поле класса указатель на другой класс , то естественно , я пропишу в деструкторе
удаление подуровней.
А как быть с самим классом ? В деструкторе если не брать удаление подуровней, больше
писать то и нечего , так как поля класса , не указатели , а статические переменные .
Нужно ли его удалять созданный класс с помощью такой конструкции ?
delete objPointer
И как правильно вообще работать с объектами классами в динамической памяти, со структурами
делал просто через делит , хотя у структуры есть тоже деструктор .
Спасибо заранее ?
Ответы
Ответ 1
При вызове оператора delete для указателя на объект класса будет вызван его деструктор.
В деструкторе вы должны освободить всю память, которую динамически выделили в конструкторе
или других методах данного класса.
Для тех полей класса, которые объявлены в статической памяти, будет вызван соответствующий
деструктор автоматически.
Если класс, к которому относится данный объект, является потомком другого класса,
то потом будет вызван деструктор базового класса и его полей (не забывайте, что деструктор
должен быть объявлен как виртуальный, иначе будет вызван деструктор только того класса,
указателем на который вы пользуетесь. Могут быть утечки памяти и прочие Ужасные Вещи).
И не забывайте, что разница между struct и class только в том, какие права доступа
присваиваются полям данного типа по-умолчанию (public для struct и private для class).
Больше никаких различий в типах объявления нет!
Ответ 2
Смотрите.
Каждый объект является (точнее, может являться) ответственным за другие объекты.
Часто ответственный объект содержит указатель на объекты, за которые он отвечает. В
этом случае разумной политикой будет удалить эти объекты в своём деструкторе.
Таким образом, когда внешний код удалит ответственный объект, при этом вызовется
деструктор, и «внутренние» объекты тоже будут удалены.
Более хорошая и современная идея такая: вместо обыкновенного указателя на объект
хранить смарт-указатель. Тогда в деструкторе можно не заботиться о подчинённых объектах,
они будут удалены автоматически.
Если есть возможность автоматизировать часть логики программы, этим не стоит пренебрегать.
Ответ 3
Вы можете создавать и удалять экземпляр класса так, как написали. Тогда при его удалении
c помощью delete работает деструктор класса, написанный Вами или созданный компилятором
по умолчанию.
Если Вы создали экземпляр в стеке: someObj obj , то этот же деструктор сработает
при выходе из зоны видимиости или в конце программы.
Закрыт. Этот вопрос не по теме. Ответы на него в данный
момент не принимаются.
Хотите улучшить этот вопрос? Переформулируйте вопрос,
чтобы он соответствовал тематике «Stack Overflow на русском».
Закрыт 4 года назад.
Написал своё первое приложение, это секундомер с таймером. Теперь хочу выложить его
в Play Market и даже не знаю, что дальше. Основа — платная версия, но думаю сделать
ещё урезанную бесплатную.
В общем, как я понял, это очень ответственный шаг (очень часто приходится видеть
плохие приложения чуть ли не в топе, а хорошие и интересные приложения всего с 10—50
загрузками). Но вот не знаю, что делать в первую очередь? Где выкладывать обзоры? Стоит
ли вкладывать деньги в продвижение (изначально решил продвигать бесплатно)? Приложение
имеет и английскую версию, и если с русскоязычной ещё более-менее понятно, то с английской
полный ноль.
Ответы
Ответ 1
Без лайт версии - не будет работать
Запостите лайт версию в разные аппсторы (сейчас их много). Навскидку: Amazon, Samsung
Apps, GetJar, Appoke и проч.
Русскую версию выложите на 4PDA
Прочтите книгу про маркетинг Android апп
Не ленитесь отвечать на сообщения юзеров
Ответ 2
Секундомер-таймер платный? Не стоит. Сейчас не 2008 год, когда не было подобных приложений.
Это все было раньше. Сейчас это все не работает. Большая конкуренция - большие компании
- много хороших приложений + смотря на какой рынок вы ориентируетесь. На русский точно
не стоит надеяться особо с платной версией. Выше Вам уже посоветовали что можно начать
делать, согласен, добавлю только что еще можно выложить в SlideMe локализованную на
анг язык версию и можно попробовать добавить AdMob.
Кроме этого, если Вы этого не делали, то попробуйте: проанализируйте конкурентов
вашего приложения и добавьте что-то особенное в свой апп. Если вкратце, то вот какой
он должен быть примерно:
- Должна быть симпатичная графика и UI
- Как можно меньше багов и особенно крашей
- Видео работы приложения
- Красивые скриншоты
- Особенность который нет у конкурентов
- Можно сделать сайт/блог о приложении и добавить ссылку везде на этот сайт
И еще отличным советом будет методика ребят из 37signals(авторов книги Rework): делайте
приложение которым вы сами будете пользоваться. Отсюда будет очень много полезного,
ведь вы сразу поймете свою аудитории и возможные косяки или сильные стороны своего
приложения.
Я думаю сейчас, чтобы приложение было более-менее популярным важна идея + качественная
реализация + платное продвижение в спец. сайты(хотя бы в начале).
Ответ 3
маркеты AppBrain, AndroidPit
Опубликуйте статью на Хабре: 100500 установок, заодно много ценных замечаний. Таких
тестеров еще поискать
ну и по поводу плтных установок, тоже верно. Для Android можно вот этими ребятами
пользоваться http://advertmobile.net/
Есть ли в jquery, или написанная на стандартном js функция проигрывания увеличение
числа? Например:
Увеличение значения от 1% до 80%, быстро проиграв все значения промежуточные значения
(2,3,4...)?
Ответы
Ответ 1
http://jsfiddle.net/8Sdpy/ — только ради спортивного интереса
jQuery(function ($)
// Добавляем hook "number"
$.Tween.propHooks.number = {
get: function ( tween ){
var num = tween.elem.innerHTML.replace(/^[^\d-]+/, '');
return parseFloat(num) || 0;
},
set: function( tween ) {
var opts = tween.options;
tween.elem.innerHTML = (opts.prefix || '')
+ tween.now.toFixed(opts.fixed || 0)
+ (opts.postfix || '');
}
};
// Используем
$('#target')
.html('1%')
.animate({ number: 80 }, { duration: 'slow', postfix: '%', fixed: 2 });
});
Или совсем просто — http://jsfiddle.net/QGY28/
$('#num').animate({ num: 90 - 3/* - начало */ }, {
duration: 5000,
step: function (num){
this.innerHTML = (num + 3).toFixed(2) + '%'
}
});
Как установить расширение в браузер хром программным путем.
Запуск файла на компе → расширение добавлено в хром
Как это реализовать, какой файл в хроме отвечает за управление установленными расширениями?
Кое как разобрался с документацией, создал файл nojpnepbplnoojhiinbpegidccgolald.json
(в качестве имени использовал id приложения, его получил установив плагин к себе в
хром и скопировав его id) в папке
C:\Users\<имя пользователя>\AppData\Local\Google\Chrome\Application\31.0.1650.63\Extensions
со следующим содержанием:
{
"external_crx": "C:\Sdsattings.crx",
"external_version": "1.0"
}
crx файл разместил на диске C, перезапускаю хром и ничего не происходит
Ответы
Ответ 1
Приветствую.
В целях безопасности в Chrome на Mac / Windows можно устанавливать расширения только
с Chrome Web Store. Т.е. по факту в Chrome добавляется информация о том какое расширение
надо обновить и после запуска браузера он подгружает расширение.
Windows
1.1. В Windows установка происходит через реестр в раздел:
32-bit HKEY_LOCAL_MACHINE\Software\Google\Chrome\Extensions
64-bit HKEY_LOCAL_MACHINE\Software\Wow6432Node\Google\Chrome\Extensions
1.2. Создать новый ключ (папка) вида aaaaaaaaaabbbbbbbbbbcccccccccc (ID расширения
в Chrome Web Store)
1.3. Внутри этого ключа создать свойство update_url со значением https://clients2.google.com/service/update2/crx
(ссылка на Chrome Web Store)
Mac
2.1. Создать файл типа aaaaaaaaaabbbbbbbbbbcccccccccc.json (ID расширения в Chrome
Web Store)
2.2. Содержимое файла должно быть таким
{
"external_update_url": "https://clients2.google.com/service/update2/crx"
}
2.3. Положить его в папку:
для определенного пользователя ~USERNAME/Library/Application Support/Google/Chrome/External
Extensions/
для всех /Library/Application Support/Google/Chrome/External Extensions/
Вариант для Linux
Для Linux можно устанавливать как с удаленного источника, так и с локального .crx файла
3.1. Создать файл типа aaaaaaaaaabbbbbbbbbbcccccccccc.json (ID расширения)
3.2. Содержимое файла должно быть таким
при установке с локального файла
{
"external_crx": "/path/to/extension.crx",
"external_version": "1.0"
}
при установке по ссылке (пример)
{
"external_update_url": "http://myhost.com/mytestextension/updates.xml"
}
3.3. Положить файл в любую из папок (должен иметь права на чтение всеми):
/opt/google/chrome/extensions/
/usr/share/google-chrome/extensions/
Также возможно установить расширение простым открытием .crx файла из Chrome, если
браузер запустить с флагом –enable-easy-off-store-extension-install
Ответ 2
Почему бы не поискать ответ на официальном сайте?
Developer's Guide -> Finishing -> Other Deployment Options
http://developer.chrome.com/extensions/external_extensions.html
Например две функции:
var func1 = function(var1, var2,..., varN) {
var first = var1 + var2;
var second = first + varN;
....
}
var func2 = function() {
}
как-то можно передать переменные, например first во вторую функцию не объявляя её
глобальной?
Ответы
Ответ 1
Как вариант так:
var func1 = function(var1, var2,..., varN) {
var first = var1 + var2;
var second = first + varN;
....
return first;
}
var func2 = function(getFirst) {
var first = getFirst(var1, var2,..., varN);
}
Вообще, функция должна что-то принимать и что-то возвращать. Лучше будет даже так:
var func1 = function (args) {var first; .....; return first},
func2 = function (first)) {};
func1(func1(args));
Во избежания такой некрасивой вложенности лучше использовать временные переменные:
var func1 = ....,
func2 = ......,
first = func1(args);
func2(first)
Ответ 2
Например:
Вернуть переменную из одной функции, получить во второй:
function f1(){
var trololo = 345;
return trololo;
}
function f2(){
var myTrololo = f1();
}
Объявить вторую функцию внутри первой :
function f1(){
var trololo = 345;
function f2(){
var myTrololo = trololo;
}
}
Использовать для связи какой-нибудь объект, к которому будут иметь доступ обе функции:
var GodObj = {};
function f1(){
var trololo = 345;
GodObj.lala = trololo;
}
function f2(){
var myTrololo = GodObj.lala;
}
Собственно вызвать вторую функцию из первой, с некоторым обычно необязательным параметром,
но конечно тут зависит от того что эта функция делает
function f1(){
var trololo = 345;
f2(trololo);
}
functin f2(trololo){
if(typeof(trololo)!='undefined') myTrololo = trololo;// Если такой параметр есть
}
Алгоритм поиска корня числа num. В алгоритме также используется sqrt, это приблизительный
корень.
function getsqrt (num, sqrt) {
sqrt = 0.5*(sqrt+num/sqrt);
var sqrtPrev = sqrt;
while (Math.abs(sqrt-sqrtPrev) <= (sqrt-sqrtPrev)) {
sqrtPrev = sqrt;
sqrt = 0.5*(sqrt+num/sqrt);
}
return sqrt;
}
Какова сложность алгоритма? Линейная? Логарифмическая и т.д? Меня смущает просто
деления на 2. Мне кажется, это линейная O(n)или логарифмическая.
Обновление
Мои рассуждения следующие: мы имеем один цикл, значит степень первая. Но я не уверен,
что это линейная типа O(n). Потому что в задании есть 0.5*(sqrt+num/sqrt). Соответственно
мне кажется, что это ускоряет поиск корня, нежели мы бы делили просто на 2 или методом
перебора. Прав ли я, что это логарифмическая зависимость по основанию 2?
Ответы
Ответ 1
Для Вашей функции сложно судить, какая у нее сложность - у Вас два аргумента. Поэтому,
нужно либо фиксировать один аргумент, либо вводить зависимость между ними.
Я использовал простое - sqrt = num/2. и пошел по самому простому пути - тестил на
разных значениях аргумента и построить график (это один из способов узнать сложность).
Мое мнение - сложность константная (или очень близка к ней).
num десятые микросекунды (10^-7)
1 -> 32
2 -> 27
4 -> 24
8 -> 24
16 -> 23
32 -> 23
64 -> 23
128 -> 26
256 -> 24
512 -> 23
1024 -> 23
2048 -> 24
4096 -> 23
8192 -> 23
16384 -> 23
32768 -> 22
65536 -> 23
131072 -> 24
262144 -> 23
524288 -> 23
1048576 -> 24
2097152 -> 23
4194304 -> 24
8388608 -> 23
16777216 -> 23
33554432 -> 24
67108864 -> 23
134217728 -> 23
268435456 -> 24
536870912 -> 24
Как видно на первых проходах идет "прогрев" (это отрабатывает jit компилятор).
Кстати, в Вашем коде есть одна ошибка - он иногда зависает. И зависает, если попытаться
извлечь корень из числа, для которого он рациональный. (как минимум зависает на 4 и 10000).
полный код для тестов и исправление (все тестилось на node.js).
function getsqrt (num, sqrt) {
sqrt = 0.5*(sqrt+num/sqrt);
var sqrtPrev = sqrt;
while (Math.abs(sqrt-sqrtPrev) < (sqrt-sqrtPrev)) {
sqrtPrev = sqrt;
sqrt = 0.5*(sqrt+num/sqrt);
}
return sqrt;
}
function test(num)
{
var start = new Date();
for (var i = 0; i < 10000000; i++) {
getsqrt(num, num / 2);
}
var end = new Date();
return end.setTime(end.getTime()-start.getTime())
}
for (var i = 1; i < 1000000000; i = i*2) {
console.log(i + " -> " + test(i));
}
P.S. В тегах указано с++, а код написан на JavaScript. Поэтому свой код я написал
также на JavaScript.
Обновление
я разобрался, почему она константа. Потому что цикл обычно выполняется 1 раз или
0 (так у меня получается). Присмотритесь к условию
while (Math.abs(sqrt-sqrtPrev) <= (sqrt-sqrtPrev))
sqrt-sqrtPrev используется в обеих частях! А если вспомните, то есть такое правило
- не сравнивать на равенство вещественные числа (на больше-меньше можно, но осторожно,
если числа близкие).
Если там равно, то оно сработает только в том случае, если sqrt-sqrtPrev > 0 и немного
повезет (на самом деле, если разница представима конечной двоичной дробью).
Поэтому, сложность у алгоритма константная:).
Ответ 2
Если чуть-чуть изменить приведенный фрагмент программы следующим образом:
function getsqrt (num, sqrt) {
var sqrtPrev = sqrt;
sqrt = 0.5*(sqrt+num/sqrt);
while (Math.abs(sqrt-sqrtPrev) > 1e-5) {
sqrtPrev = sqrt;
sqrt = 0.5*(sqrt+num/sqrt);
}
return sqrt;
}
То получившаяся программа будет реализацией известного метода Ньютона для отыскания
корня уравнения x^2 - num = 0.
Про метод Ньютона известно, что (в некоторой окрестности решения) он обладает квадратичной
сходимостью. Это означает, что на каждом следующем шаге значение невязки diff, то есть
разности между значением sqrt и квадратным корнем из num, меньше, чем квадрат невязки,
вычисленной на предыдущем шаге.
Число итераций цикла зависит как от величины числа num, так и от величины требуемой
точности. В примере эта величина фиксирована: 1e-5, но допустим, что она также может
меняться. Обозначим требуемую точность именем eps. Тогда для метода Ньютона можно дать
оценку числа итераций O(log log (num/eps)).
Использую библиотеку с открытым кодом JGraphX (http://www.jgraph.com/) для визуализации
графов. Возникла такая проблема, при попытке экспорта модели в XML-файл возникает ошибка
: java.lang.ClassCastException: [F cannot be cast to [Ljava.lang.Object. Я нашёл место
в коде библиотеки, где эта ошибка генерится:
/**
* Encodes the child objects of arrays, maps and collections.
*
* @param enc Codec that controls the encoding process.
* @param obj Object whose child objects should be encoded.
* @param node XML node that contains the encoded object.
*/
protected void encodeElements(mxCodec enc, Object obj, Node node)
{
if (obj.getClass().isArray())
{
Object[] tmp = (Object[]) obj; // Здесь всё рушиться
for (int i = 0; i < tmp.length; i++)
{
encodeValue(enc, obj, null, tmp[i], node);
}
}
else if (obj instanceof Map) ...
При трассировке выяснилось, что obj действительно хранит массив из 10 числе типа
Float. Для понимания ситуации, я сделал следующий пример, чтобы разобраться :
public class Encast {
public static void main(String[] args) {
Object obj = createMassiv();
Object[] tmp = (Object[]) obj;
}
public static Float[] createMassiv() {
Float[] obj = new Float[10];
for(int i = 0; i < obj.length; ++i) {
obj[i] = (float) (i + 1);
}
return obj;
}
}
В моём примере всё работает и преобразуется. Я не могу понять, в чём проблема в библиотеке,
и как я могу переписать так, чтобы не было ошибки.
Ответы
Ответ 1
Проблема воспроизведется, если вы будете использовать тип float[] вместо Float[].
В Java массивы коварианты по типу, и т.к. тип Float является производным от Object,
то и тип Float[] является производным от Object[]. Но примитивный тип float не является
производным от ссылочного типа Object.
Всем привет, уже весь инет перерыл. Представим себе такую ситуацию. У нас есть игра
на js, в которой пользователь набирает очки. Эти очки нужно сохранить на сервер для
создания таблицы рекордов. Рекорд вместе с id пользователя и токеном через ajax передается
на php сервер. Если токен защищает аккаунт пользователя от стороннего вмешательства,
то как защитить рекорд от замены его самим пользователем? Ведь юзеру ничего не мешает
подменить запрос, взяв свой токен, и легко попасть на первое место. Переменная, хранящая
текущий результат на клиенте, зашита в функцию-обработчик. Поэтому пользователь ее
просто так не изменит. А вот запрос подделает запросто. Какие средства защиты нужно
использовать? Помогите!
Ответы
Ответ 1
Ну первое, что приходит в голову - обеспечить ситуацию, при которой сервер будет
знать, что запрос пришел именно из игры, а не создан искусственно. Предлагаю в игре
генерировать некий хеш, завязанный на глобальное время и зашифрованный только вам известным
способом. На сервере принимать его, генерировать свой хеш по тому же принципу и сравнивать.
Ответ 2
Цитата с хабра:
Написал метод который дублировал результат. В одном параметре
передавался реальный, в другом
шифрованный результат, методом замены
символа по ключу. А далее, на сервере
оба сравниваются и если что-то не
соответствует, то – бан по аккаунту.
И еще, сервер отправляет
сгенрированный ключ при первом
обращении. Клиент же, должен его
вернуть с результатом. Без этого
ключа, результат не примется и если
все соответствует, и все проходит
проверку, то результат записывается в
БД, и генерируется новый ключ, который
опять отдается клиенту. Это сделано
для того, чтобы повторно запрос с
результатом не могли отправить, как
делается в программе «Charles».
Подключаю в хедере
IE8 видит нормально и меняет фон головы, а вот IE11 и 10 не воспринимают эту систему,почему
и как это исправить, на всякий
Ответы
Ответ 1
http://msdn.microsoft.com/en-us/library/ie/hh801214%28v=vs.85%29.aspx
A page using Conditional Comments
worked as intended in Windows Internet
Explorer 9, but no longer works in
Internet Explorer 10.
Ответ 2
Поддержка условных комментариев в стандартном режиме и режиме совместимости Internet
Explorer 10 была удалена для улучшения взаимодействия и совместимости с HTML5. Это
означает, что условные комментарии теперь обрабатываются как обычные комментарии, так
же как в других браузерах. Это изменение может повлиять на страницы, написанные специально
для Windows Internet Explorer, или страницы, использующие определитель браузера и подстраивающиеся
под Internet Explorer.
Страница, использующая условные комментарии, работает нормально в Windows Internet
Explorer 9, но не работает в Internet Explorer 10.
Используйте css хак:
@media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {
/* стили только для IE10 */
}
Ответ 3
Да, спасибо для 10 и 11 версии подключается так
Вы используйете IE
Начнём с того, что я новичок, пользуюсь IDEA. Интересуюсь, как разработкой оффлайн
приложений, так и web-, даже про Android был бы не против, что-нибудь услышать, хотя
и меньше, чем про первые два варианта. Напишу сначала, что я знаю о тестировании:
1) В некоторых книгах (и не только) рекомендуется такой подход к программированию,
при котором перед тем, как писать непосредственно код, пишутся тесты. Если я правильно
понял, тесты пишутся ко ВСЕМ классам, которые будут в коде. Но во первых, написание
теста к классу требует такого же времени, что и написание самого класса, а иногда и
гораздо большего. Во вторых, в тех ситуация, которые я учёл, класс будет функционировать
исправно (за исключением опечаток), а в тех ситуациях, которые я не учёл, тест будет
проходится успешно (т.к. они не заложены в тест). И в третьих, иногда не знаешь как
будет выглядеть некий класс, до тех пор, пока его не реализуешь, более того, и после
реализации будет много раз видоизменятся, иногда кардинальным образом - например: попробовал
один подход - скорость отработки низкая, попробовал совершенно другой (с другим набором
классов и интерфейсов) - выше.
Так вот стоит ли прибегать к такому подходу? И как быть с учётом всего, выше написанного?
Меня как-то панический страх берёт писать тесты все геттеры/сеттеры...
2) Слышал про автотестирование... даже видел обрывок записи, где записывался макрос
мыши, как для автоматической прокачки персонажа в играх. Но знаю крайне мало, то, что
мне попадалось выглядит сложно и непонятно, а самое главное не ясно, нужно ли это вобще...
Просветите, как новичку воспользоваться автотестированием в различных ситуация (офф,
web)? Какие программные инструменты для этого использовать? Какой русскоязычной литературой
можно руководствоваться?
3) Может я ещё что-то упустил в области тестирования... Буду рад любым наставлениям
;)
Ответы
Ответ 1
есты пишутся ко ВСЕМ классам
писать тесты абсолютно на все - не самая здравая идея.
в тех ситуация, которые я учёл, класс будет функционировать исправно
не факт. У вас же нет никакой гарантии, что вы правильно реализовали "то, что учли".
Проверить это как раз помогут тесты
в тех ситуациях, которые я не учёл, тест будет проходится успешно (т.к. они не заложены
в тест)
разработчик обязан знать, что должен делать тот или иной его класс, соответственно,
тестировать свои классы он должен на предмет соответствия этому "предназначению". Следовательно,
описанная вами ситуация не имеет смысла
иногда не знаешь как будет выглядеть некий класс, до тех пор, пока его не реализуешь
см. выше - разработчик должен знать, что будет делать создаваемый им класс, и тестировать
его именно с этой точки зрения. Следовательно, тестированию не особо интересны детали
реализации этого класса (и возможные изменения в этой реализации)
И наконец, не сочтите за занудство, но выглядит ужасно:
не "координальным", а кардинальным, и не "просвятите", а просветите
Ответ 2
Важна мера во всем. Тестируются обычно сложные случаи. А так вообще все тестировать
никаких сил не хватит. Потом ведь надо будет писать тесты тестов (я серьезно).
К тому же тестирование бывает разным: юнит тесты, нагрузочное тестирование, функциональное
тестирование и т.д. Не зря среди прогерской братии есть специальность тестировщик/тестер.
Прогер должен тестировать конечный результат своего труда. Скажем написали некий
класс/иерархию выполняющую допустим скачивание контента из сети. Логичным было бы написать
юнит тест проверяющий идентичность скачанного со скачиваемым. В общем идея проста:
Вам мудрое руководство поставило некую задачу;
Вы ее решили;
Теперь надо доказать, что решение работает. Для этого пишете юнит тест (серию юнит
тестов) доказывающих работоспособность вашего решения;
Показываете руководителю;
Профит.
P.S. Касательно бинов. Если вам поставили задачу написать бины - значит придется
писать юнит тесты на ваши бины. Такова се ля ви :)
Ответ 3
Вот хороший плагин для Eclipse, который определяет уровень, насколько ваш код покрыт
тестами. http://eclemma.org/
Написал я программу, выложил на гитхаб (https://github.com/KaPaHgaIII/namegenerator).
Нет ли такого места, где можно показать свой код более опытным людям, чтобы указали
на недочёты?
Ответы
Ответ 1
1)
cmdArguments.getGender().substring(0, 1).toLowerCase().equals("m") //жуть
cmdArguments.getGender() == Genders.MALE //старые добрые enum
а вот в getGender нужно писать что-то типо этого
switch(gender) {
case "male": return Gender.MALE;
//и т.п.
2)
Random randomizer = new Random(System.nanoTime()); //мелкая придирка, но System.nanoTime()
писать не обязательно
3) в
for (int i = 0; i < cmdArguments.getCount(); i++) {
System.out.println(engine.generateName(cmdArguments.getLength()));
}
System.out.println лучше выносить в отдельный метод, причём лучше в отдельный класс
(правило mvc)
4)
catch (FileNotFoundException e) {
System.out.println(e);
} catch (IOException e) {
System.out.println(e);
}
меняем на
catch (Exception e) {
System.err.println(e); //обратите внимание на err
}
5)
readData("male_names.txt");
здесь тоже бы хорошо было бы заюзать enum. А вдруг в будущем вы будете считывать
данные не с файла, а с интернета? Будете url каждый раз указывать?
6) огромное количество
s.substring(i, i + 2);
А почему +2, а не +3? Не помешал бы мелкий комментарий рядом
7) Отдельное текстовое пояснение как работает алгоритм. Иначе он будет понятен только вам
0) Но главное, после моих рекомендаций не превратиться в Бориса из известной статьи
Как два программиста хлеб пекли
Ответ 2
Ох, не люблю всех этих телепаций уровня "введите то, введите сё, введите хрень ту
экзит". Чем стандартная командная строка не угодила-то?
-g, --gender= m[ale], f[emale], b[oth]
-l, --length= name length
-n, --number= number of names to generate
Понятно и без лишних телодвижений. Тем более что стандартный GNU getopt() для Java
существует давно.
Как сделать с помощью "ip" уникальные просмотры?
$id = $_GET["id"];
qeurycount = mysql_query("SELECT count FROM news WHERE news_id='$id'",$link);
$resultcount = mysql_fetch_array($qeurycount);
$newcount = $resultcount["count"] + 1;
$update = mysql_query ("UPDATE news SET count='$newcount' WHERE news_id='$id'",$link);
}
Ответы
Ответ 1
Здесь что-то не понятное, вам нужна уникальность по IP? Но где проверка IP вообще?
Где запись, если этот IP пришел впервые?
Ответ 2
Ребята, вы так запросто вставляете $_SERVER['REMOTE_ADDR']; в запрос, кто вам сказал,
что там айпишник а не злобный sql inj? Кто мешает заголовок подменить?
По теме - ip не является показателем уникальности, есть целые города сидящие через
один ip
При первом посещении, ставьте уникальный id в куки, или еще лучше в сессию, и по
нему считайте. От чистки куков это в общем не спасет.
Ответ 3
При посещении страницы пользователем нужно записывать IP в отдельную таблицу, если
в той таблице такой ip не был записан ранее
CREATE TABLE `news_show` (
`ip` varchar(32) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
Количество всех просмотров
echo mysql_result(mysql_query("SELECT COUNT(*) FROM news_show"),0);
Запись посетителя
$ip=$_SERVER['REMOTE_ADDR'];
if(mysql_result(mysql_query("SELECT COUNT(*) FROM news_show WHERE ip='$ip'
LIMIT 1"),0)==0)
mysql_query("INSERT INTO news_show (`ip`) values('$ip')");
Ответ 4
На таком уровне php вам нужен как просто посылатель одного запроса:
UPDATE news SET count = count + 1 WHERE news_id = :id
Я бы не рекомендовал, впрочем, реализовывать счетчики в той же таблице. Таблица новостей
вряд ли обновляется так часто, как счетчики, это может помешать кэшированию на стороне
БД, да и приложение становится менее устойчивым - с отвалившимися каунтерами выжить
можно, новостями - нет.
Добрый день!
Специально пересмотрел все заданные вопросы про PhpStorm (на сей момент их было 39)
и не нашел ответа на свой вопрос.
Имеется PhpStorm 6-ой версии с Default визуальной цветовой схемой.
Создаю PHP файл и естественно, пишу PHP код.
Предположим, выделяю переменную $a, PhpStorm подсвечивает другие переменные $a, однако
очень тускло.
Вопрос в следующем: как можно изменить цвет подсветки других таких же переменных ?
(чтобы было ярко и четко подсвечивались)
Копаюсь в Settings -> Editor -> Colors&Fonts -> PHP (все перебрал из списка, однако
подсветку таких же переменных не смог пока найти...
Подскажите пожалуйста что-нибудь по данному поводу.
Заранее спасибо!
Ответы
Ответ 1
IDE Settings - Editor - Colors & Fonts - General - Identifier under caret
Возможно ли написать на bash команду, которая комментирует сама себя в файле?
Ответы
Ответ 1
Ну например:
[vladd@Kenga] [19:49:21] [~]
{0,120}$> cat selfmod.sh
#!/bin/bash
echo start
T=$(mktemp -u) && sed '/DELETETHISLINE/s/^/#/' <$0 >$T && rm -f $0 && mv $T $0
echo finish
[vladd@Kenga] [19:49:24] [~]
{0,121}$> ./selfmod.sh
start
finish
[vladd@Kenga] [19:49:29] [~]
{0,122}$> cat selfmod.sh
#!/bin/bash
echo start
#T=$(mktemp -u) && sed '/DELETETHISLINE/s/^/#/' <$0 >$T && rm -f $0 && mv $T $0
echo finish
Если нужно не пересоздавать файл, можно так:
#!/bin/bash
echo start
sed -i '/DELETETHISLINE/s/^/#/' "$0"
echo finish
Оказывается, sed умеет редактировать файл in place, так что получилось даже проще.
Ответ 2
Как мне кажется, я нашёл идеальное решение моей задачи.
Тут самое главное переменная $LINENO, которая и показывает номер текущей строки в
скрипте.
Теперь можно делать скрипт, который после успешного выполнения команды сам себя комментирует.
ls && sed -i ''$LINENO' s/^/#/' $0
Задача:
Некоторые скобочные структуры правильные, другие - неправильные. Ваша задача: определить,
правильная ли скобочная структура.
Вход: Слово в алфавите из двух круглых скобочек ( и ), [, ], {, }. Длина слова меньше
40001.
Выход: Либо 'NO', либо 'YES' без кавычек.
Вот текст моей программы, но она не проходит все тесты. Не пойму, где ошибка. И
какие тесты она не проходит (не смог таких придумать).
int main()
{
std::string s;
std::cin >> s;
std::stack < char > st;
std::stack < char > st1;
std::stack < char > st2;
bool f = true, g = true, k = true;
int index = 0;
while (index < s.length() && f && g && k)
{
if (s[index] == ')')
{
f = (!st.empty());
if (f)
st.pop();
}
else
if (s[index] == ']')
{
g = (!st1.empty());
if (g)
st1.pop();
}
else
if (s[index] == '}')
{
k = (!st2.empty());
if (k)
st2.pop();
}
else
if (s[index] == '(')
{
st.push(s[index]);
}
else
if (s[index] == '[')
{
st1.push(s[index]);
}
else
if (s[index] == '{')
{
st2.push(s[index]);
}
index++;
}
std::cout << (((k && f && g && st.empty() && st1.empty() && st2.empty()) ? "YES"
: "NO")) << std::endl;
}
Прошу помощи.
Обновление
Программа работает, но на каких-то тестах она работает неправильно (при загрузке
в систему проходят не все тесты). Какие там тесты, мне не известно. И я не могу выяснить,
при каких условиях она ошибается, прошу помочь именно в этом.
Просто хочу научиться работать со стеком. Не подумал о Вашем примере. Попробовал
реализовать заново с помощью трех стеков, Ваш пример теперь работает правильно, но
снова не проходит все тесты в системе. Код изменил в ответе. Посмотрите, пожалуйста.
Ответы
Ответ 1
Я не вижу, чтобы у вас использовался флаг k в проверке while.
Как вы думаете, что произойдет при входе "[{))" в вашу программу и является ли это
правильным.
Не указаны критерии правильности скобочных структур, к примеру, могут ли они быть
пересекающимися.
По хорошему, вам нужно считать количество каждого вида скобок, без всяких стеков
и прочих наворотов: int round=0, rect=0, figure=0;
Если опустилось ниже 0 во время прохождения, значит ошибка в структуре скобок и выполнить
break, если по окончанию строки не все стали, снова равны нулю, тоже ошибка.
UPDATE 1 (неверный)
Тогда можно ограничиться одним стеком и организовать проверку только выталкиваемого
из стека значения pop(), чтобы оно содержало аналогичную открывающую скобку. Ясли не
ошибаюсь, этого достаточно:
if (s[index] == ')') f = (!st.empty() && st.pop()=='(');
if (s[index] == ']') g = (!st.empty() && st.pop()=='[');
if (s[index] == '}') k = (!st.empty() && st.pop()=='{');
if (s[index]=='['||s[index]=='{'||s[index]=='(') st.push(s[index]);
Соответственно проверка флагов в цикле и при выводе ответа (+ на пустоту стека) остается.
UPDATE 2 (исправленный)
@doomsday, прошу прощения, я не часто имею дело с С++, для возврата значения из стека
надо использовать вместо pop() функция top(). То есть по идее следующий код должен
решать поставленную задачу.
#include
#include
#include
using namespace std;
int main(){
string str;
stack st;
int index = 0;
bool f = true, g = true, k = true;
cin >> str;
while (index < str.length() && f && g && k)
{
char chr = str[index];
if (chr == '[' || chr == '{' || chr == '(') st.push(chr);
if (chr == ')') f = (!st.empty() && st.top() == '(');
if (chr == ']') g = (!st.empty() && st.top() == '[');
if (chr == '}') k = (!st.empty() && st.top() == '{');
index++;
}
cout << (k && f && g && st.empty() ? "YES" : "NO") << endl;
return 0;
}
Ответ 2
Не помню решения этой задачи без рекурсии. Через рекурсию решается более-менее просто,
вот так:
class Braces
{
public:
enum class br_type
{
_br_head,
_br_round,
_br_square,
_br_figure
};
Braces(br_type type, char* line) : _type(type)
{
int runner = 0;
while(line[runner] == '(' || line[runner] == '[' or line[runner] == '{')
{
if (line[runner] == '(')
_sub_braces.push_back(Braces(br_type::_br_round, &line[runner + 1]));
else if (line[runner] == '[')
_sub_braces.push_back(Braces(br_type::_br_square, &line[runner + 1]));
else if (line[runner] == '{')
_sub_braces.push_back(Braces(br_type::_br_figure, &line[runner +
1]));
runner += _sub_braces.back().size();
}
if (runner == strlen(line) && _type == br_type::_br_head)
return;
if (line[runner] == ')' && _type != br_type::_br_round)
throw std::exception("NO");
if (line[runner] == ']' && _type != br_type::_br_square)
throw std::exception("NO");
if (line[runner] == '}' && _type != br_type::_br_figure)
throw std::exception("NO");
}
int size() { return 2 + sum_sizes(_sub_braces); }
int sum_sizes(vector& braces)
{
int res = 0;
for (auto& br : braces)
{
res += br.size();
}
return res;
}
br_type _type;
vector _sub_braces;
};
Код написал тут, т.е. не проверял, но идея рекурсии, думаю, ясна. Если внешний объект
(с типом _br_head, которому передается вся строка) создатся без exception, то надо
выводить ОК, иначе сообщение exception-а. Сделав nasty эксепшны, можно даже указать,
на какой именно вложенности получена ошибка.
Как известно, после удаления элемента из середины списка ArrayList, часть массива,
которая следовала после данного элемента, перезаписывается на позицию влево, чтоб перекрыть
пустую ячейку. Если стоит задача удалить несколько элементов из середины списка одной
операцией (т. е. чтоб избежать многоразовой перезаписи массива), как это можно сделать?
Ответы
Ответ 1
Как обычно - наследованием:
public class MyArrayList extends ArrayList {
public void remove(int startIndex, int endIndex) {
//здесь и придумывайте свой гениальный код
}
}
Ответ 2
Используйте методы removeAll и sublist. sublist - для создания коллекции (пула элементов),
которую нужно удалить. А removeAll уже для удаления элементов.
Пример кода:
public static void main(String[] args){
List list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
list.add(6);
list.add(7);
list.add(8);
List sublist = list.subList(2,5); // Удаляем с 2 по 4й элемент включительно
list.removeAll(sublist);
System.out.println(list); //[1, 2, 6, 7, 8]
}
}
//В одну строку
public static void main(String[] args){
List list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
list.add(6);
list.add(7);
list.add(8);
list.removeAll(list.subList(2,5));
System.out.println(list); //[1, 2, 6, 7, 8]
}
}
Ответ 3
использовать removeAll(Collection c)
наследовать и использовать removeRange(int fromIndex, int toIndex)
Ответ 4
Не нужно ничего наследовать, вреда от этого больше, чем пользы. Нефинальные классы
контейнеров были ошибкой.
Условимся, что из списка длины n нужно удалить m элементов.
Формализую вопрос: m удалений, по O(n) каждое, стоит O(m×n); как можно ускорить процесс?
Пользуясь тем, что ArrayList#set стоит O(1), нужно сначала отметить все элементы
как удалённые:
list.set(index, REMOVED);
где REMOVED — это приватная константа, которая в обычных условиях в списке не окаженся:
private static final Object REMOVED = new Object();
Дженерики будут мешать вставке произвольных Objectов, поэтому придётся воспользоваться
стиранием и сделать unchecked cast.
((List) list).set(index, REMOVED);
После этого в листе есть посторонние элементы. Осторожно: list.get(removedIndex)
приведёт к ClassCastException, подробнее — см. heap pollution.
Теперь нужно удалить все элементы, которые отмечены для удаления. Вызов list.remove(REMOVED)
удалит только первое вхождение; нам нужен метод removeAll, который удалит все элементы
переданной коллекции из данного списка:
list.removeAll(COLLECTION_OF_REMOVED);
где
private static final Collection